package chpt_06_02_reposbilitychain;

import org.springframework.util.ObjectUtils;

import java.util.UUID;

/**
 * @author Ping
 * @date 2023/5/10 22:42
 **/
public class ResponsiblityDemo {
    public static void main(String args[]) {
        /**
         * build handling chain/process
         */
        Handler requestHandler = new Director().setNext(new Manager()) ;

        LeaveRequest leaveRequest = new LeaveRequest("zhangsan",
                "cause", 2) ;
        requestHandler.handle(leaveRequest);
        System.out.println("result: request " +  leaveRequest.getId()
                + " " + leaveRequest.getResult()) ;
        leaveRequest = new LeaveRequest("lisi",
                "cause", 9) ;
        requestHandler.handle(leaveRequest) ;
        System.out.println("request " +  leaveRequest.getId() + " "
                + leaveRequest.getResult()) ;
        leaveRequest = new LeaveRequest("wangwu", "cause",
                12) ;
        requestHandler.handle(leaveRequest);
    }
}

class LeaveRequest {
    public static final String APPROVED = "approved" ;
    public static final String REJECTED = "rejected" ;
    private String id ;
    private String userName ;
    private String cause ;
    private int days ;
    private String result ;

    public LeaveRequest(String userName, String cause, int days) {
        this.id = UUID.randomUUID().toString() ;
        this.userName = userName;
        this.cause = cause;
        this.days = days;
    }

    public String getUserName() {
        return userName;
    }

    public String getCause() {
        return cause;
    }

    public int getDays() {
        return days;
    }

    public void approve() {
        this.result = APPROVED ;
    }
    public void reject() {
        this.result = REJECTED ;
    }
    public String getResult() {
        return this.result ;
    }

    public String getId() {
        return id;
    }
}

/**
 * Handler role: TOP
 */
interface Handler {
    public Handler next() ;
    public void handle(LeaveRequest leaveRequest) ;
    public boolean hasNext() ;
    public Handler setNext(Handler nextHandler) ;
}

/**
 * abstract Handler role:
 */
abstract class AbstractHandler implements Handler {
    protected Handler nextHandler ;

    @Override
    public Handler next() {
        return this.nextHandler;
    }
    @Override
    public boolean hasNext() {
        return ! ObjectUtils.isEmpty(this.nextHandler);
    }

    @Override
    public Handler setNext(Handler nextHandler) {
        this.nextHandler = nextHandler ;
        return this;
    }
}

class Director extends AbstractHandler {


    @Override
    public void handle(LeaveRequest leaveRequest) {
        if (leaveRequest.getDays() <= 3) {
            System.out.println("[INFO] approved by director.") ;
            leaveRequest.approve();
            return ;
        }
        System.out.println("[INFO] the request can not processed by director .") ;
        if (this.hasNext()) {
            this.next().handle(leaveRequest);
        }

    }
}
class Manager extends  AbstractHandler {
    @Override
    public void handle(LeaveRequest leaveRequest) {
        if (leaveRequest.getDays() <= 10) {
            System.out.println("[INFO] approved by manager.") ;
            leaveRequest.approve();
            return ;
        }
        System.out.println("[INFO] the request can not processed by manager .") ;
        if (this.hasNext()) {
            this.next().handle(leaveRequest);
        } else {

        }

    }
}